package com.shareyi.jshop.autocode.dbutil

import com.shareyi.joywindow.sys.utils.BindResource;
import com.shareyi.jshop.autocode.dbutil.filter.DictColumnProcessor
import com.shareyi.jshop.autocode.dbutil.filter.PKFilter;
import com.shareyi.jshop.autocode.dbutil.filter.NameExpressionFilter;
import com.shareyi.jshop.autocode.domain.Column;
import com.shareyi.jshop.autocode.domain.Option
import com.shareyi.jshop.autocode.domain.SimpleTableInfo
import com.shareyi.jshop.autocode.domain.TableDefine;
import com.shareyi.jshop.autocode.domain.TableModel
import com.shareyi.jshop.autocode.tableutil.TableNameUtil;
import com.shareyi.jshop.autocode.tableutil.PubUtils;
import com.shareyi.jshop.autocode.utils.AutoCodeConstant;
import com.shareyi.fileutil.FileUtil;

import groovy.sql.Sql
import org.apache.commons.lang.StringUtils

class DBTableUtil {
	
	
	
	public static void main(String[] args) {
		String tableName="user_info";
	//	generateDbTableModel(tableName);
	}
	
	/**
	 * 生成数据库表名的tableModel xml文件
	 * @param tName 表名
	 */
	static String generateDbTableModel(String tName,String cnnamePage,String driverName,String url,
		String username,String pwd,String tableModelDir,int smartFlag) throws Exception{
		//def sql=Sql.newInstance("jdbc:mysql://localhost:3306/test","root","12345","com.mysql.jdbc.Driver");
		def sql=Sql.newInstance(url,username,pwd,driverName);
		TableNameUtil tableNameUtil=new TableNameUtil();
		
		TableModel tableModel=new TableModel();
		TableDefine tableDefine1=new TableDefine();
		def columns=[];
		tableDefine1.columns=columns;
		tableModel.tableDefine=tableDefine1;
		
		
		def meta = sql.connection.metaData
		String[] s=new String[1];
		s[0]="TABLE";
		def tableInfo=meta.getTables(null,null,tName,s);
		if(tableInfo.next()) {
			String tableName=tableInfo.getString("TABLE_NAME");
			tableDefine1.id=tableNameUtil.upperFirst(tableNameUtil.convertToBeanNames(tableName));
			tableDefine1.dbTableName=tableName;

			if(StringUtils.isNotBlank(cnnamePage)){
				tableDefine1.cnname=cnnamePage;
			}else{
				tableDefine1.cnname=tableInfo.getString("REMARKS");
				if(tableDefine1.cnname==null||tableDefine1.cnname==''){
					tableDefine1.cnname=tableDefine1.id;
				}
			}
		}else{
			throw new Exception(tName+"表不存在！执行失败！");
		}
		
		def cols=meta.getColumns(null,null,tName,null);
		while (cols.next()) {
			Column column= new Column();
			column.columnName=cols.getString('COLUMN_NAME');
			column.dataName=tableNameUtil.convertToBeanNames(column.columnName);
			column.cnname=cols.getString('REMARKS');
			column.columnType=cols.getString('TYPE_NAME');
			column.length=cols.getInt('COLUMN_SIZE');
			column.canBeNull=cols.getString('IS_NULLABLE')=="YES";
			column.isPK=cols.getString('IS_AUTOINCREMENT')=="YES";
			column.canBeNull=cols.getString('IS_NULLABLE')=="YES";
			column.jspTag=tableNameUtil.getJspTag(column.columnType);

			if(column.cnname==null||column.cnname==''){
				column.cnname=column.columnName;
			}
			
			//进行一次trim操作
			column.comment=column.cnname.trim();
			column.cnname=column.comment;
			
			columns.add(column);
		}

		
		Properties  dbTableUtilPro=BindResource.getBindProperties(AutoCodeConstant.BIND_DBTABLEUTIL);
		DBTableUtil.initUtils(dbTableUtilPro);
		
		//对字典项字段进行预处理，分解出字典项数据
		dictColumnProcessor.process(tableModel, columns);
		
		List queryListColumns=null;
		List addListColumns=null;
		List updateListColumns=null;
		List viewListColumns=null;
		List createTimeColumns=null;
		List updateTimeColumns=null;
		List searchKeyColumns=null;
		//不启用
		if(smartFlag==2){
			queryListColumns=columns;
			addListColumns=columns;
			updateListColumns=columns;
			viewListColumns=columns;
			searchKeyColumns=[];
			createTimeColumns=[];
			updateTimeColumns=[];
		}else{
			 queryListColumns=queryListFilter.filterColumns(columns);
			 addListColumns=addListFilter.filterColumns(columns);
			 updateListColumns=updateListFilter.filterColumns(columns);
			 viewListColumns=viewListFilter.filterColumns(columns);
			 createTimeColumns=createTimeFilter.filterColumns(columns);
			 updateTimeColumns=updateTimeFilter.filterColumns(columns);
			 searchKeyColumns=searchKeyFilter.filterColumns(columns);
		}
		
		
		def sw = new StringWriter()
		sw.append("""<?xml version="1.0" encoding="UTF-8" ?> \n""");
		def xml = new groovy.xml.MarkupBuilder(sw)
		xml.tableModel{
			tableDefine(id:tableDefine1.id,cnname:tableDefine1.cnname,dbTableName:tableDefine1.dbTableName){
				columns.each {
					return column(dataName:it.dataName,columnName:it.columnName,
					cnname:it.cnname,columnType:it.columnType,canBeNull:it.canBeNull,
					readonly: it.readonly,isPK:it.isPK,length:it.length,jspTag:it.jspTag,
					dictName: it.dictName, comment:it.comment)
				}
			}
			searchKeys(PubUtils.joinColumnNames(searchKeyColumns))
			orderColumns{
				pKColumnFilter.filterColumns(columns).each { pkColumn->
					return orderColumn(orderType:"desc",pkColumn.columnName)
				}
			}
			queryList(PubUtils.joinColumnNames(queryListColumns))
			addList(PubUtils.joinColumnNames(addListColumns))
			updateList(PubUtils.joinColumnNames(updateListColumns))
			viewList(PubUtils.joinColumnNames(viewListColumns))
			allColumn(PubUtils.joinColumnNames(columns))
			createTime(PubUtils.joinColumnNames(createTimeColumns))
			updateTime(PubUtils.joinColumnNames(updateTimeColumns))
			dicts{
				tableModel.dictMap.each { entry->
					def dictDomain=entry.value;
					return dict(id:dictDomain.id, name: dictDomain.name){
						dictDomain.optionList.each {
							Option op=it;
							option(value: op.value, cssClass: op.cssClass , op.name)
						}
					}
					
				}
			}
		}
		
		File f=new File(FileUtil.contactPath(tableModelDir,tableDefine1.id?.trim()+".xml"));
		FileUtil.makeSureFileExsit(f);
		//换行符号替换为Windows的换行符号
		f.withWriter("utf-8")
				{ writer ->
					writer.write sw.toString().replaceAll("\n","\r\n");
				}
		
		print "table "+tName+"的XML文件成功生成，在："+f.absolutePath;
		return f.absolutePath;
	}



	/**
	 * 生成数据库表名的tableModel xml文件
	 * @param tName 表名
	 */
	static List<SimpleTableInfo> getTableList(String driverName,String url,String username,String pwd) throws Exception{
		//def sql=Sql.newInstance("jdbc:mysql://localhost:3306/test","root","12345","com.mysql.jdbc.Driver");
		def sql=Sql.newInstance(url,username,pwd,driverName);
		TableNameUtil tableNameUtil=new TableNameUtil();




		def meta = sql.connection.metaData
		String[] s=new String[1];
		s[0]="TABLE";

		def list=[];
		def tableInfo=meta.getTables(null,null,null,s);
		while(tableInfo.next()) {
			SimpleTableInfo tInfo=new SimpleTableInfo();
			String tableName=tableInfo.getString("TABLE_NAME");
			tInfo.tableName=tableName;
			tInfo.id=tableNameUtil.upperFirst(tableNameUtil.convertToBeanNames(tableName));
			tInfo.cnname=tableInfo.getString("REMARKS");
			if(tInfo.cnname==null||tInfo.cnname==''){
				tInfo.cnname=tInfo.id;
			}
			list.add(tInfo)
		}

		return list;

	}





	static String createTimeExp="gmtCreate,created";
	static String updateTimeExp="gmtModify,modified";
	static String queryListExp="^gmtCreate,created,*note,*remark";
	static String addListExp="^gmtCreate,created,gmtModify,modified";
	static String updateListExp="^gmtCreate,created,gmtModify,modified";
	static String viewListExp="";
	static String searchKeyExp="name,*state,*status";
	
	
	static ColumnFilter createTimeFilter,updateTimeFilter,pKColumnFilter,
			queryListFilter,addListFilter,updateListFilter,viewListFilter,searchKeyFilter;
	
	static ColumnProcessor dictColumnProcessor;	

		
	static void initUtils(Properties properties){
		if(properties!=null){
			createTimeExp=properties.get("createTimeExp");
			updateTimeExp=properties.get("updateTimeExp");
			queryListExp=properties.get("queryListExp");
			addListExp=properties.get("addListExp");
			updateListExp=properties.get("updateListExp");
			viewListExp=properties.get("viewListExp");
			searchKeyExp=properties.get("searchKeyExp");
			
		}
		
		createTimeFilter=new NameExpressionFilter(createTimeExp);
		updateTimeFilter=new NameExpressionFilter(updateTimeExp);
		
		queryListFilter=new NameExpressionFilter(queryListExp);
		addListFilter=new NameExpressionFilter(addListExp);
		updateListFilter=new NameExpressionFilter(updateListExp);
		viewListFilter=new NameExpressionFilter(viewListExp);
		searchKeyFilter=new NameExpressionFilter(searchKeyExp);
		
		pKColumnFilter=new PKFilter();
		
		dictColumnProcessor=new DictColumnProcessor();
		
	}
}
